﻿namespace NTLib.Core.Configuration.Attributes
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using NTLib.Core.Reflection;
    using System.Threading;

    /// <summary>
    /// This attribute make the relay during the configuration process to the type define.
    /// </summary>
    /// <seealso cref="System.Attribute" />
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
    public class ProviderConfigurationAttribute : BaseConfigurationAttribute
    {
        #region Properties

        /// <summary>
        /// Gets or sets the provider of the configuration values.
        /// This type must implement the interface <see cref="IConfigurationProvider"/>
        /// </summary>
        public Type Provider { get; set; }

        #endregion

        #region Ctor

        /// <summary>
        /// Initializes a new instance of the <see cref="ProviderConfigurationAttribute"/> class.
        /// </summary>
        /// <param name="provider"> The type of the configuration values's provider.
        /// This type must implement the interface <see cref="IConfigurationProvider"/></param>
        public ProviderConfigurationAttribute(Type provider)
        {
            this.Provider = provider;
            if (this.Provider == null)
                throw new ArgumentNullException(nameof(provider));

            if (!this.Provider.IsOrInheritOf(typeof(IConfigurationProvider)))
                throw new ArgumentException(string.Format(Strings.ExceptionResources.BadTypeException, typeof(IConfigurationProvider)));
        }

        #endregion


        #region Methods

        /// <summary>
        /// Collects the configuration value.
        /// </summary>
        /// <param name="host"></param>
        /// <param name="context"></param>
        /// <param name="token"></param>
        /// <returns>
        /// Return the collection of value extract from the describe process
        /// </returns>
        public override ConfigurationCollection CollectConfigurationValue(Type host, object context = null, CancellationToken token = default(CancellationToken))
        {
            var provider = Activator.CreateInstance(this.Provider) as IConfigurationProvider;

            return provider.CollectConfigurationValue(host, context, token);
        }

        #endregion
    }
}
